package io.sundial.console.datasource.web;

import com.google.common.base.Optional;
import io.sundial.console.Pagination;
import io.sundial.console.datasource.core.Datasource;
import io.sundial.console.datasource.core.DatasourceType;
import io.sundial.console.datasource.service.DatasourceService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.sql.SQLException;

/**
 * 数据源控制器
 *
 * @author Payne 646742615@qq.com
 * 2019/1/3 15:16
 * @tag 数据源
 */
@CrossOrigin
@RestController
@RequestMapping("/api/datasource")
public class DatasourceController {

    @Resource
    private DatasourceService datasourceServiceBean;

    /**
     * 验证数据源是否有效
     *
     * @param param 数据源对象
     * @return 数据源验证结果
     */
    @PostMapping("/verification")
    @ResponseBody
    public DatasourceVerifyResult verify(@RequestBody @Valid DatasourceVerifyParam param) {
        DatasourceVerifyResult result = new DatasourceVerifyResult();

        Datasource datasource = new Datasource();

        datasource.setName(param.getName());
        datasource.setType(param.getType());
        datasource.setAddress(param.getAddress());
        datasource.setCatalog(param.getCatalog());
        datasource.setUsername(param.getUsername());
        datasource.setPassword(param.getPassword());
        datasource.setDescription(Optional.fromNullable(param.getDescription()).or(""));

        DatasourceType type = param.getType();
        try {
            type.verify(datasource);
        } catch (SQLException e) {
            return result.error(400, Optional.fromNullable(e.getMessage()).or(e.getClass().getSimpleName() + ":" + e.getErrorCode() + " " + e.getSQLState()));
        }

        return new DatasourceVerifyResult();
    }

    /**
     * 新建数据源
     *
     * @param param 数据源对象
     * @return 数据源新建结果
     */
    @PostMapping
    @ResponseBody
    public DatasourceCreateResult create(@RequestBody @Valid DatasourceCreateParam param) {
        DatasourceCreateResult cResult = new DatasourceCreateResult();
        DatasourceVerifyResult vResult = verify(param);
        if (vResult.getCode() != 0) {
            return cResult.wrap(vResult);
        }

        Datasource datasource = new Datasource();

        datasource.setName(param.getName());
        datasource.setType(param.getType());
        datasource.setAddress(param.getAddress());
        datasource.setCatalog(param.getCatalog());
        datasource.setUsername(param.getUsername());
        datasource.setPassword(param.getPassword());
        datasource.setDescription(Optional.fromNullable(param.getDescription()).or(""));

        datasource.setVersion(0L);
        datasource.setDisabled(false);

        datasourceServiceBean.save(datasource);

        return cResult;
    }

    /**
     * 分页查询数据源
     *
     * @param param 数据源分页查询参数
     * @return 数据源分页查询结果
     */
    @GetMapping
    @ResponseBody
    public DatasourceSearchResult search(@Valid DatasourceSearchParam param) {
        DatasourceSearchResult result = new DatasourceSearchResult(param);

        Pagination<Datasource> pagination = datasourceServiceBean.search(param.getPageNo(), param.getPageSize(), param.getKeyword());

        result.setTotal(pagination.getTotal());
        result.setItems(pagination.getItems());

        return result;
    }

    /**
     * 更新数据源的状态
     * 禁用：disabled = true
     * 启用：disabled = false
     *
     * @param name  数据源名称
     * @param param 数据源状态更新参数
     * @return 数据源状态更新结果
     */
    @PutMapping("/{name}/status")
    @ResponseBody
    public DatasourceStatusResult status(@PathVariable("name") String name, @RequestBody @Valid DatasourceStatusParam param) {
        DatasourceStatusResult result = new DatasourceStatusResult();

        datasourceServiceBean.shift(name, param.isDisabled());

        return result;
    }

    /**
     * 删除数据源
     *
     * @param name  数据源名称
     * @param param 数据源删除参数
     * @return 数据源删除结果
     */
    @DeleteMapping("/{name}")
    @ResponseBody
    public DatasourceRemoveResult remove(@PathVariable("name") String name, @Valid DatasourceRemoveParam param) {
        DatasourceRemoveResult result = new DatasourceRemoveResult();

        datasourceServiceBean.remove(name);

        return result;
    }

    /**
     * 更新数据源
     *
     * @param name  数据源名称
     * @param param 数据源对象
     * @return 数据源更新结果
     */
    @PutMapping("/{name}")
    @ResponseBody
    public DatasourceUpdateResult update(@PathVariable("name") String name, @RequestBody @Valid DatasourceUpdateParam param) {
        DatasourceUpdateResult uResult = new DatasourceUpdateResult();
        DatasourceVerifyResult vResult = verify(param);
        if (vResult.getCode() != 0) {
            return uResult.wrap(vResult);
        }

        Datasource datasource = new Datasource();

        datasource.setName(param.getName());
        datasource.setType(param.getType());
        datasource.setAddress(param.getAddress());
        datasource.setCatalog(param.getCatalog());
        datasource.setUsername(param.getUsername());
        datasource.setPassword(param.getPassword());
        datasource.setDescription(Optional.fromNullable(param.getDescription()).or(""));

        datasourceServiceBean.update(name, datasource);

        return uResult;
    }

}
